﻿using System;
using Special = System.Collections.Specialized;
using System.ComponentModel;

namespace Xylee.Common
{
    /// <summary>
    /// Property manager maintains the consistency in all properties 
    /// that are associated with a given context or viewable item.
    /// Items can be persisted or managed via the INotify property c
    /// change events using the PropertyChanged event notifier.
    /// </summary>
    public class PropertyManager : INotifyPropertyChanged
    {
        private System.Collections.IDictionary dictionary;

        /// <summary>
        /// Constructs the property manager by creating 
        /// a new instance of the hybrid dictionary for 
        /// property management using key-value pairs.
        /// </summary>
        public PropertyManager()
        {
            this.dictionary = new Special.HybridDictionary();
        }

        /// <summary>
        /// Returns or sets a particular property value to/from the 
        /// hybrid dictionary list of key/value pairs.
        /// </summary>
        /// <param name="propertyName"></param>
        /// <returns></returns>
        public object this[string propertyName]
        {
            get
            {
                return dictionary[propertyName];
            }
            set
            {
                if (dictionary[propertyName] != value)
                {
                    dictionary[propertyName] = value;
                    if (PropertyChanged != null)
                        PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
                }
            }
        }

        /// <summary>
        /// Sets the value of the given property value by 
        /// using the indexer specified in the property manager 
        /// hybrid dictionary key-value pair collection.
        /// </summary>
        /// <param name="propertyName">The name of the property to set the value.</param>
        /// <param name="value">The value to set to the property.</param>
        public void SetValue(string propertyName, object value)
        {
            this[propertyName] = value;
        }

        /// <summary>
        /// Returns the value of the given property value by using 
        /// the indexer specified in the property manager 
        /// hybrid dictionary key-value pair collection.
        /// </summary>
        /// <param name="propertyName">The name of the property to obtain the value.</param>
        /// <returns>The object value associated with the property.</returns>
        public object GetValue(string propertyName)
        {
            return this[propertyName];
        }

        public void NotifyChange(object sender, string propertyName)
        {
            if (PropertyChanged != null)
                PropertyChanged(sender, new PropertyChangedEventArgs(propertyName));
        }

        #region INotifyPropertyChanged Members

        /// <summary>
        /// Notifies when a property has changed in the property manager.
        /// </summary>
        public event PropertyChangedEventHandler PropertyChanged;

        #endregion
    }
}
